#include "yaffs_packedtags2.h"
#include "mtd_sim.h"
#include "nand.h"

#include "yaffs_read.h"


int
yaffs_read_chunk_with_tags(struct mtd_info *mtd, int nand_chunk, uint8_t *data, struct yaffs_ext_tags *tags )
{

	struct mtd_oob_ops ops;
	size_t dummy;
	int retval = 0;
	/* XXX: dont know which is the common case */
	int no_tags_ecc = 0;
	int inband_tags = 0;
	
	uint8_t spare_buffer[512];

	//loff_t addr = ((loff_t) nand_chunk) * totalBytesPerChunk;
	loff_t addr = ((loff_t) nand_chunk) * chunkSize;
	struct yaffs_packed_tags2 pt;
	int packed_tags_size =
	    no_tags_ecc ? sizeof(pt.t) : sizeof(pt);
	void *packed_tags_ptr =
	    no_tags_ecc ? (void *)&pt.t : (void *)&pt;

	if (inband_tags || (data && !tags)) {
		retval = mtd->read(mtd, addr, totalBytesPerChunk,
				   &dummy, data);
	} else if (tags) {
		ops.mode = MTD_OOB_AUTO;
		ops.ooblen = packed_tags_size;
		ops.len = data ? chunkSize : packed_tags_size;
		ops.ooboffs = 0;
		ops.datbuf = data;
		ops.oobbuf = spare_buffer;
		memset(spare_buffer, 0, sizeof(spare_buffer));
		retval = mtd->read_oob(mtd, addr, &ops);
	}

	if (inband_tags && tags) {
		struct yaffs_packed_tags2_tags_only *pt2tp;

		pt2tp =
			(struct yaffs_packed_tags2_tags_only *)
				&data[chunkSize];
		yaffs_unpack_tags2_tags_only(tags, pt2tp);
	} else if (tags) {
		memcpy(packed_tags_ptr,
		       spare_buffer,
		       packed_tags_size);
		yaffs_unpack_tags2(tags, &pt, !no_tags_ecc);
	}

//	if (tags && retval == -EBADMSG &&
//	    tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
//		tags->ecc_result = YAFFS_ECC_RESULT_UNFIXED;
//		dev->n_ecc_unfixed++;
//	}
//	if (tags && retval == -EUCLEAN &&
//	    tags->ecc_result == YAFFS_ECC_RESULT_NO_ERROR) {
//		tags->ecc_result = YAFFS_ECC_RESULT_FIXED;
//		dev->n_ecc_fixed++;
//	}
	if (retval == 0)
		return YAFFS_OK;

	return YAFFS_FAIL;

}

